#include <assert.h>
#include <fstream>

#include "../tools/Log.h"
#include "../tools/xml/ticpp.h"
#include "Game.h"
#include "UnitType.h"

using namespace std;

map <string, UnitType*> UnitType::unit_types;

UnitType::UnitType(string name, unsigned Attack_damage, unsigned Attack_rate, unsigned Build_speed, unsigned Initial_health,
				   unsigned Speed)
	: name(name), attack_damage(Attack_damage), attack_rate(Attack_rate), build_speed(Build_speed), initial_health(Initial_health), 
	speed(Speed)
{ }

string UnitType::get_name() { return name; }
unsigned UnitType::get_initial_health() { return initial_health; }
unsigned UnitType::get_attack_damage() { return attack_damage; }
unsigned UnitType::get_attack_rate() { return attack_rate; }
unsigned UnitType::get_speed() { return speed; }
unsigned UnitType::get_build_speed() { return build_speed; }
Model UnitType::get_model() { return m; }

void UnitType::load_from_file(string file_name)
{
	using namespace ticpp;
	
	try	{
		Document doc(file_name);
		doc.LoadFile();
		
		Node* node = doc.FirstChild(), *unit_type = NULL;
		
		while((unit_type = node->IterateChildren(unit_type)) != NULL)
		{
			string node_type;
			unit_type->GetValue(&node_type);
			
			if (node_type == "unit_type")
			{
				Element *unit_type_el = unit_type->ToElement();
				UnitType *ut = new UnitType(unit_type_el->GetAttribute("name"),
											atoi(unit_type_el->GetAttribute("damage").c_str()),
											atoi(unit_type_el->GetAttribute("attack_rate").c_str()),
											atoi(unit_type_el->GetAttribute("build_speed").c_str()),
											atoi(unit_type_el->GetAttribute("health").c_str()),
											atoi(unit_type_el->GetAttribute("speed").c_str()));
				
				ut->m.load(unit_type_el->GetAttribute("model").c_str());	// Load model
				
				unit_types[ut->name] = ut;
				
			} else {
				lout << "Ignoring invalid line in unit type configuration file." << endl;
			}
		}
	} catch( Exception& ex ) {
		lout << "WARNING: Game - Error parsing \"" << file_name << "\": " << ex.what() << endl;
	}
}

UnitType* UnitType::find_unit_type_by_name(string unit_type_name)
{
	if (unit_types.find(unit_type_name) != unit_types.end())
		return unit_types[unit_type_name];
	
	return NULL;
}
